package com.bjbn.service.impl;

import com.bjbn.bean.MonitorResponse;
import com.bjbn.bean.TopicInfo;
import com.bjbn.service.ActivemqMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * ActiveMQ监控服务实现类
 * 
 * @author bjbn
 */
@Slf4j
@Service
public class ActivemqMonitorServiceImpl implements ActivemqMonitorService {

    @Value("${monitor.data-retention-minutes:60}")
    private int dataRetentionMinutes;

    /**
     * Topic信息缓存
     */
    private final Map<String, TopicInfo> topicCache = new ConcurrentHashMap<>();

    /**
     * 初始化Topic列表
     */
    @PostConstruct
    @Override
    public void initializeTopics() {
        log.info("初始化ActiveMQ Topic列表...");
        
        // 根据方案文档中的Topic列表初始化
        addTopic("csb.ImportMeteorologicalDataInfoSrv.v0", "气象", "00001");
        addTopic("csb.ImportADSBDataInfoSrv.v0", "adsb", "00002");
        addTopic("csb.ImportDfStandDataInfoSrv.v0", "df-stand", "00003");
        addTopic("csb.ImportBsStandDataInfoSrv.v0", "bs-stand", "00004");
        addTopic("csb.ImportFzVehicleDataInfoSrv.v0", "飞管车辆台账", "00005");
        addTopic("csb.ImportApronRadarDataInfoSrv.v0", "机坪雷达融合信息", "00006");
        addTopic("csb.ImportFzLocationDataInfoSrv.v0", "飞管车辆轨迹", "00007");
        addTopic("csb.ImportBaseAirportDataInfoSrv.v0", "机场基础信息", "00008");
        addTopic("csb.ImportBaseAirstandDataInfoSrv.v0", "机位基础信息", "00009");
        addTopic("csb.ImportBaseAirtaskDataInfoSrv.v0", "航班任务基础信息", "00010");
        addTopic("csb.ImportBaseAirwayDataInfoSrv.v0", "航司基础信息", "00011");
        addTopic("csb.ImportDFltairlineDataInfoSrv.v0", "航班航站动态信息", "00012");
        addTopic("csb.ImportDFltcounterDataInfoSrv.v0", "航班值机柜台", "00013");
        addTopic("csb.ImportDFltgateDataInfoSrv.v0", "航班登机门", "00014");
        addTopic("csb.ImportDFltinfoDataInfoSrv.v0", "航班主表", "00015");
        addTopic("csb.ImportDFltlugeftchDataInfoSrv.v0", "航班行李提取转盘", "00016");
        addTopic("csb.ImportDFltlugloadDataInfoSrv.v0", "航班行李滑槽口", "00017");
        addTopic("csb.ImportDFltshareDataInfoSrv.v0", "共享航班", "00018");
        addTopic("csb.ImportDFltstandDataInfoSrv.v0", "航班机位", "00019");
        addTopic("csb.ImportDFltSgDynDataInfoSrv.v0", "航班保障动态节点", "00020");
        addTopic("csb.ImportFlightPassengerAndLuggageDataInfoSrv.v0", "旅客人数和行李数量", "00022");
        addTopic("csb.ImportBridgeDataInfoSrv.v0", "廊桥信息", "00023");
        addTopic("csb.ImportPlaneAirconditionDataInfoSrv.v0", "廊桥飞机空调", "00024");
        addTopic("csb.ImportPowerInfoDataInfoSrv.v0", "廊桥电源", "00025");
        addTopic("csb.ImportScheduleFlightDataInfoSrv.v0", "航班季度计划", "00029");
        addTopic("csb.ImportTemporaryFlightDataInfoSrv.v0", "航班临时计划", "00030");
        addTopic("csb.ImportMetarParseDataInfoSrv.v0", "METAR气象报文解析数据", "00031");
        addTopic("csb.ImportTafParseDataInfoSrv.v0", "TAF气象报文解析数据", "00032");
        log.info("ActiveMQ Topic列表初始化完成，共{}个Topic", topicCache.size());
    }

    /**
     * 添加Topic
     */
    private void addTopic(String topicName, String description, String code) {
        TopicInfo topicInfo = new TopicInfo(topicName, description, code);
        topicInfo.setStatus("NO_DATA");
        topicCache.put(topicName, topicInfo);
    }

    @Override
    public MonitorResponse getMonitorStatus() {
        LocalDateTime currentTime = LocalDateTime.now();
        List<TopicInfo> topics = getAllTopics();
        
        // 更新每个Topic的状态和时间差
        topics.forEach(this::updateTopicStatus);
        
        return new MonitorResponse(200, "获取监控状态成功", currentTime, topics);
    }

    @Override
    public TopicInfo getTopicStatus(String topicName) {
        TopicInfo topicInfo = topicCache.get(topicName);
        if (topicInfo != null) {
            updateTopicStatus(topicInfo);
        }
        return topicInfo;
    }

    @Override
    public List<TopicInfo> getAllTopics() {
        return topicCache.values().stream()
                .sorted((t1, t2) -> t1.getCode().compareTo(t2.getCode()))
                .collect(Collectors.toList());
    }

    @Override
    public void updateTopicLastDataTime(String topicName) {
        TopicInfo topicInfo = topicCache.get(topicName);
        if (topicInfo != null) {
            LocalDateTime now = LocalDateTime.now();
            topicInfo.setLastDataTime(now);
            topicInfo.setUpdateTime(now);
            topicInfo.setMessageCount(topicInfo.getMessageCount() + 1);
            log.debug("更新Topic {} 的最新数据时间: {}", topicName, now);
        } else {
            log.warn("未找到Topic: {}", topicName);
        }
    }

    /**
     * 更新Topic状态
     */
    private void updateTopicStatus(TopicInfo topicInfo) {
        LocalDateTime currentTime = LocalDateTime.now();
        LocalDateTime lastDataTime = topicInfo.getLastDataTime();
        
        if (lastDataTime == null) {
            topicInfo.setStatus("NO_DATA");
            topicInfo.setTimeDiffSeconds(null);
        } else {
            long timeDiffSeconds = ChronoUnit.SECONDS.between(lastDataTime, currentTime);
            topicInfo.setTimeDiffSeconds(timeDiffSeconds);
            
            // 判断状态：超过5分钟为延迟，超过1小时为无数据
            if (timeDiffSeconds > 3600) {
                topicInfo.setStatus("NO_DATA");
            } else if (timeDiffSeconds > 300) {
                topicInfo.setStatus("DELAYED");
            } else {
                topicInfo.setStatus("NORMAL");
            }
        }
        
        topicInfo.setUpdateTime(currentTime);
    }

    /**
     * 清理过期数据
     */
    public void cleanupExpiredData() {
        LocalDateTime cutoffTime = LocalDateTime.now().minusMinutes(dataRetentionMinutes);
        topicCache.values().removeIf(topic -> 
            topic.getLastDataTime() != null && topic.getLastDataTime().isBefore(cutoffTime)
        );
    }
} 